package com.jackstraw.jack_base.rules.service.impl;

import com.jackstraw.jack_base.rules.entity.dto.RuleExecutionObject;
import com.jackstraw.jack_base.rules.exception.BadRuleException;
import com.jackstraw.jack_base.rules.service.RuleBizService;
import com.jackstraw.jack_base.rules.service.RuleExcuteService;
import com.jackstraw.jack_base.rules.service.RuleService;
import com.jackstraw.jack_base.util.JsonUtil;
import com.jackstraw.jack_base.util.SpringUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;

@Slf4j
public abstract class AbstractRuleExcuteService implements RuleExcuteService {

    private final List<Long> ruleGroupIdS = new CopyOnWriteArrayList<>();

    /**
     * 获取RuleService
     *
     * @return
     */
    protected RuleBizService ruleBizService() {
        return SpringUtil.getBean("ruleBizServiceImpl");
    }

    @Override
    public Map<String, Object> excute(String sceneId, Map<String, Object> body) {
        RuleExecutionObject ruleExecutionObject = ruleExecutionObject(body);

        for (Long ruleGroupId : getRuleGroupIdS()) {
            ruleExecutionObject = ruleBizService().executeGroup(ruleGroupId, ruleExecutionObject);
        }
        Map<String, Object> factObjectMap = ruleExecutionObject.getFactObjectMap();
        body.clear();
        body.put("_result", factObjectMap);
        return body;
    }

    protected RuleExecutionObject ruleExecutionObject(Map<String, Object> body) {
        RuleExecutionObject ruleExecutionObject = new RuleExecutionObject();
        Map<String, Object> factObjectfactObjectMap = body.get("factObjects") == null ? new HashMap<>() : (Map<String, Object>) body.get("factObjects");
        body.put("factObjects", factObjectfactObjectMap);
        factObjectfactObjectMap.keySet().forEach((fullClassName) -> {
            Object o = factObjectfactObjectMap.get(fullClassName);
            if (o instanceof Map) {
                try {
                    Class<?> aClass = Class.forName(fullClassName);
                    Object mapToBean = JsonUtil.mapToBean((Map) o, aClass);
                    factObjectfactObjectMap.put(fullClassName, mapToBean);
                } catch (ClassNotFoundException e) {
                    log.error("转换BOM对象异常，异常原因为:{}", e);
                    throw new BadRuleException("001", "转换BOM对象异常,请联系管理人员");
                }
            }
        });
        ruleExecutionObject.addFactObject(factObjectfactObjectMap);
        ruleExecutionObject.setGlobal("log", log);
        ruleExecutionObject.setRuleName(body.get("ruleName") != null ? String.valueOf(body.get("ruleName")) : null);
        ruleExecutionObject.setGroupName(body.get("groupName") != null ? String.valueOf(body.get("groupName")) : null);
        return ruleExecutionObject;
    }

    @Override
    public List<Long> getRuleGroupIdS() {
        return ruleGroupIdS;
    }

    @Override
    public void setRuleGroupIdS(List<Long> ruleGroupIdS) {
        this.ruleGroupIdS.clear();
        this.ruleGroupIdS.addAll(ruleGroupIdS);
    }

    /**
     * 获取RuleService
     *
     * @return
     */
    protected abstract RuleService ruleService();

}
